﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ArmoryData;
using System.Net;
using System.IO;

namespace ArmoryViewer
{
    static class Updater
    {
        public delegate void UpdateProgressChangedEventHandler(object sender, UpdateProgressChangedEventArgs e);
        public static event UpdateProgressChangedEventHandler UpdateProgressChanged;
        public delegate void UpdateCompletedEventHandler(object sender, EventArgs e);
        public static event UpdateCompletedEventHandler UpdateCompleted;

        static void OnUpdateProgressChanged(UpdateProgressChangedEventArgs e)
        {
            if (UpdateProgressChanged == null) return;
            UpdateProgressChanged(client, e);   
        }

        static void OnUpdateCompleted()
        {
            if (UpdateCompleted == null) return;
            UpdateCompleted(client, new EventArgs());
        }

        static int downNum = 1;
        /// <summary>
        /// Gets a value indicating whether an update is available.
        /// </summary>
        /// <value><c>true</c> if an update is available; otherwise, <c>false</c>.</value>
        public static bool UpdateAvailable
        {
            get { return App.Version != ServerVersion; }
        }

        /// <summary>
        /// Gets the server version.
        /// </summary>
        /// <value>The server version.</value>
        public static string ServerVersion
        {
            get
            {
                try
                {
                    String x = Connector.GetHtml(new Uri(Settings.UpdateMirror + "version.txt")).Replace("\r", "").Replace("\n", "");
                    return x;
                }
                catch { return App.Version; } // Error finding version
            }
        }

        static WebClient client = new WebClient();

        /// <summary>
        /// Cancels the update
        /// </summary>
        public static void CancelUpdate()
        {
            client.CancelAsync();
        }

        /// <summary>
        /// Downloads the update.
        /// </summary>
        public static void DownloadUpdate()
        {
            try
            {
                client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
                client.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(client_DownloadFileCompleted);
                
                // User installed, download the setup file
                if (File.Exists(App.CurrentDirectory + "installed"))
                {
                    OnUpdateProgressChanged(new UpdateProgressChangedEventArgs(0, "Downloading setup..."));
                    client.DownloadFileAsync(new Uri(Settings.UpdateMirror + "setup"), App.CurrentDirectory + "aviewer.exe");
                }
                // User extracted, download the zip file
                else
                {
                    OnUpdateProgressChanged(new UpdateProgressChangedEventArgs(0, "Downloading zip file..."));
                    client.DownloadFileAsync(new Uri(Settings.UpdateMirror + "archive"), App.CurrentDirectory + "aviewer.zip");
                }
            }
            catch (Exception ex)
            {
                OnUpdateProgressChanged(new UpdateProgressChangedEventArgs(100, "error", ex));
            }
        }

        static void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            // Check for errors
            if (e.Error != null)
            {
                OnUpdateProgressChanged(new UpdateProgressChangedEventArgs(100, "error", e.Error));
                return;
            }

            downNum++;
            // Download the updater script
            if (downNum == 2) 
            {
                OnUpdateProgressChanged(new UpdateProgressChangedEventArgs(0, "Downloading update script..."));
                client.DownloadFileAsync(new Uri(Settings.UpdateMirror + "updater"), App.CurrentDirectory + "updater.exe");
            }
            // If we didn't install then we need 7z to extract our zip
            else if (downNum == 3 && !File.Exists(App.CurrentDirectory + "installed"))
            {
                OnUpdateProgressChanged(new UpdateProgressChangedEventArgs(0, "Downloading 7-Zip..."));
                client.DownloadFileAsync(new Uri(Settings.UpdateMirror + "7z"), App.CurrentDirectory + "7z.exe");
            }
            // We're done!
            else { OnUpdateCompleted(); }
        }

        static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            OnUpdateProgressChanged(new UpdateProgressChangedEventArgs(e.ProgressPercentage));
        }
    }
}